#pragma once
#include <iostream>
#include <stdio.h>
#include <string>
#include <sstream>
#include <jsoncpp/json/json.h>
#include <random>
#include <chrono>
#include <iomanip>
#include <atomic>

namespace rpc
{
    // 日志宏实现
#define INFOLEVEL 0
#define DELEVEL 1
#define ERRLEVEL 2
#define DEFLEVEL ERRLEVEL
#define log(level, format, ...)\
    {\
        if (level >= DEFLEVEL)\
        {\
            printf("[%s:%d] " format "\n", __FILE__, __LINE__, ##__VA_ARGS__);\
        }\
    }

#define delog(format, ...) log(DELEVEL, format, ##__VA_ARGS__)
#define infolog(format, ...) log(INFOLEVEL, format, ##__VA_ARGS__)
#define errlog(format, ...) log(ERRLEVEL, format, ##__VA_ARGS__)

    // json序列化和反序列化的实现
    static Json::Value def = []()
    {
        Json::Value def;
        Json::StreamWriterBuilder::setDefaults(&def);
        def["emitUTF8"] = true;
        return def;
    }();

    class JSON
    {
    public:
        static bool Serialization(Json::Value val, std::string &body)
        {

            Json::StreamWriterBuilder swb;
            swb.settings_ = def;
            std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
            std::stringstream ss;
            int ret = sw->write(val, &ss);
            if (ret != 0)
            {
                std::cout << "Serialization failed!";
                return false;
            }
            body = ss.str();
            return true;
        }

        static bool UnSerialization(const std::string &body, Json::Value &val)
        {
            // 先实例化一个工厂类
            Json::CharReaderBuilder crb;
            // 生产CharReader对象
            std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
            // 调用CharReader的parse函数分解String对象为Json对象
            Json::String errs;
            bool success = cr->parse(body.c_str(), body.c_str() + body.size(), &val, &errs);
            if (!success)
            {
                std::cout << " UnSerialization failed:" << errs << std::endl;
                return false;
            }

            return true;
        }
    };

    class UUID
    {
    public:
        static std::string uuid()
        {
            // 生成一个sstream对象存储结果
            std::stringstream ss;
            // 构造一个机器随机数对象
            std::random_device rd;
            // 以机器随机数种子构造伪随机数
            std::mt19937 generator(rd());
            // 构造限定范围的对象
            std::uniform_int_distribution<int> distribution(0, 255);

            // 生成特定的随机数并按照一定的格式拼接
            for (int i = 0; i < 8; i++)
            {
                if (i == 4 || i == 6)
                {
                    ss << '-';
                }
                ss << std::setw(2) << std::setfill('0') << std::hex << distribution(generator);
            }

            ss << "-";
            // 定义一个8字节序号，逐字节序号的组织成为一个16字节的数
            static std::atomic<size_t> sq(1); // 一个原子的1,写为静态类型保证得到的每个序号不一样
            size_t cur = sq.fetch_add(1);
            for (int i = 7; i >= 0; i--)
            {
                if (i == 5)
                {
                    ss << "-";
                }

                ss << std::setw(2) << std::setfill('0') << std::hex << ((cur >> i * 8) & 0xff);
            }

            return ss.str();
        }
    };
}